#include "../include/Timerfd.h"

#include <sys/timerfd.h>
#include <poll.h>
#include <unistd.h>

#include <iostream>
using std::cout;
using std::endl;


Timerfd::Timerfd(TimerfdCallback && cb, int init, int interval)
: _Timerfd(createTimerfd())
, _init(init)
, _interval(interval)
, _cb(std::move(cb))
, _isStarted(false)
{}

Timerfd::~Timerfd()
{
    close(_Timerfd);
}

void Timerfd::start()
{
    _isStarted = true;
    //设置定时器的超时时间
    setTime(_init, _interval);
    struct pollfd pfd;
    pfd.fd = _Timerfd;
    pfd.events = POLLIN;
    while(_isStarted) {
        int nready = poll(&pfd, 1, 4000);
        if(nready == -1 && errno == EINTR) {
            continue;
        } else if (nready == -1) {
            perror("poll");
        } else if (nready == 0) {
            //printf("poll timeout\n");
        } else {
            handleRead();
            if(_cb) {
                _cb();
            }
        }
    }
}

void Timerfd::stop()
{
    //停止定时器
    setTime(0,0);
    _isStarted = false;
}

void Timerfd::handleRead()
{
    uint64_t howmany = 0 ;
    int ret = read(_Timerfd, &howmany, sizeof(howmany));
    if(ret != sizeof(howmany)) {
        perror("read");
    }
}


int Timerfd::createTimerfd()
{
    int fd = timerfd_create(CLOCK_REALTIME, 0);
    if(fd < 0) {
        perror("Timerfd");
    }
    return fd;
}

void Timerfd::setTime(int init, int interval)
{
    struct itimerspec val;
    val.it_value.tv_sec = init;
    val.it_value.tv_nsec = 0;
    val.it_interval.tv_sec = interval;
    val.it_interval.tv_nsec = 0;
    int ret = timerfd_settime(_Timerfd, 0, &val, nullptr);
    if(ret < 0) {
        perror("timerfd_settime");
    }
}
